<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../node_modules/vue/dist/vue.global.js"></script>
</head>

<body>
    <div id="app">
        <!-- vue实现双向绑定 -->
        <h2>vue 实现数据响应式的效果</h2>
        <p>
            <input type="text" v-model='username'>
            <span>{{username}}</span>
        </p>
        <!-- vue 2怎么实现双向绑定 -->
        <hr />
        <h2>js 原生实现数据响应式的效果</h2>
        <p>
            <input type="text" id="userInp" oninput="editFn(this.value)">
            <span id="username"></span>
        </p>
    </div>
</body>

</html>
<script>
    const app = Vue.createApp({
        data() {
            return {
                username: '张三'
            }
        },
        methods: {
        }
    }).mount('#app')

    // 使用原生js 模拟实现vue2中语法实现的双向绑定
    //  Object.defineProperty(代理对象,{ get(){}, set(){}})

    let obj = {
        username: '李四'
    };
    // 01: 定义一个监听函数,监听原数据的变化,并实现dom 操作
    function observe(target, fn) {
        // target 为原对象,obj
        // fn: 当原对象数据修改了,执行dom 更新操作的函数
        // 02: 定义一个代理数据对象,当修改代理对象的属性的时候,然后就相当于修改了 原对象obj
        let result = {};
        Object.defineProperty(result, 'username', {
            get() {
                console.log('访问username');
                // 当访问result 属性时候,触发了get 方法
                return target.username
            },
            set(val) {
                console.log('修改了username');
                // 当访问该属性的时候,触发了set 方法,修改了原对象 obj的属性
                target['username'] = val
                // 操作更新页面dom
                fn(result)
            }
        })

        // 初始化赋值
        fn(result)

        // 将代理对象返回
        return result

    }

    //03 :调用该函数,实现数据的监听及更新,res 为代理对象
    let res = observe(obj, (result) => {
        // 操作修改dom
        document.querySelector('#userInp').value = result.username
        document.querySelector('#username').innerHTML = result.username
    })

    // console.log(res.username)
    // res.username = '李四'


    // 当表单中输入内容的时候,更新dom
    function editFn(val) {
        // console.log(val);
        res.username = val
    }



  // vue2 实现数据响应式的步骤
  // 通过 Object.defineProperty(代理对象,属性,{get(){},set(){}}) 该方法,实现对原数据的数据劫持,
  // 当修改代理对象的属性的时候,然后间接的修改了原对象的属性, 也就是说当代理对象发生变化原对象就发生变化,
  // 这样就实现了对原对象数据的监听和劫持, 然后根据更新的数据渲染dom
</script>